package ufrgs.ia.tetralath;

import javax.swing.JFrame;


import ufrgs.ia.Utils.Tools;
import ufrgs.ia.tetralath.models.GameMomentum;
import ufrgs.ia.tetralath.ui.MainWindow;

public class Tetralath {

	public static enum PLAYER {
		/** my turn */
		HUMAN(7, "Humano"),
		/** opponent turn */
		MINIMAX(13, "Minimax"), 
		/** none turn*/
		NO_ONE(0, "NO_ONE");

		private int value;
		private String name;

		PLAYER(int _value, String _name) {
			value = _value;
			name = _name;
		}

		public int getValue() {
			return value;
		}

		public String getName() {
			return name;
		}
	};

	/** win and loss are always related to me. so e.g.: OPPONENT_MOVE_LOSS means that the opponent will play and will make me lose*/
	public static enum BOARD_STATE {
		/** <b> represents - custom table <br> value - (0) </b> */
		NONE(0), 
		/** <b> represents - draw <br> value - (5) </b> */
		DRAW(5), 
		/** <b> represents - my move making me lose the game <br> value - (-12) </b> */
		MINIMAX_MOVE_LOSS(-12), 
		/** <b> represents - my move making me win the game <br> value - (12) </b> */
		MINIMAX_MOVE_WIN(12), 
		/** <b> represents - my move making me block an enemy victory <br> value - (8) </b> */
		MINIMAX_MOVE_BLOCK(8),
		/** <b> represents - opponent movement making me win the game <br> value - (10) </b> */
		HUMAN_MOVE_WIN(10), 
		/** <b> represents - opponent movement making me lose the game <br> value - (-10) </b> */
		HUMAN_MOVE_LOSS(-10),
		/** <b> represents - opponent movement blocking my victory <br> value - (-8) </b> */
		HUMAN_MOVE_BLOCK(-8);
		
		private int value;

		BOARD_STATE(int _value) {
			value = _value;
		}

		public int getValue() {
			return value;
		}
	}
	
	//NONE, DRAW, MY_MOVE_LOSS, MY_MOVE_WIN, OPPONENT_MOVE_WIN, OPPONENT_MOVE_LOSS;

	/** Number of cells available in the game */
	public static final int NUMBER_OF_BOARD_CELLS = 61;
	/** Dimension of the matrix that is going to hold the board */
	public static final int BOARD_DIMENSION = 9;

	/** Current gameboard */
	public static int[][] gameBoard = getReferenceMatrix();

	/** Current GameState  */
	public static GameMomentum currentGameMomentum;
	
	/** player that is the one playing at the moment */
	public static PLAYER currentPlayer = PLAYER.HUMAN; 

	
	public static int currentRoundNumber = 1;
	
	/**
	 * Create the GUI and show it. For thread safety, this method should be
	 * invoked from the event-dispatching thread.
	 */
	public static void main(String[] args) {
		// Schedule a job for the event-dispatching thread:
		// creating and showing this application's GUI.
		javax.swing.SwingUtilities.invokeLater(new Runnable() {
			public void run() {

				// Create and set up the window.
				JFrame frame = new JFrame("Tetralath");
				frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

				// Create and set up the content pane.
				MainWindow newContentPane = new MainWindow();
				newContentPane.setOpaque(true); // content panes must be opaque
				frame.setContentPane(newContentPane);

				// Display the window.
				frame.pack();
				frame.setVisible(true);
				
				currentGameMomentum = new GameMomentum(gameBoard);

			}
		});
	}

	/**
	 * Remember the following values: <br>
	 * Invalid cells = -1 <br>
	 * Free cell = 0 <br>
	 * Player 1 = PLAYER.PLAYER_ONE.getValue() <br>
	 * Player 2 = PLAYER.PLAYER_TWO.getValue() <br>
	 * 
	 * @return - the matrix that is the reference for the gameboard
	 */
	public static int[][] getReferenceMatrix() {
		int[][] gameBoardReference = new int[BOARD_DIMENSION][BOARD_DIMENSION];

		for (int i = 0; i < BOARD_DIMENSION; i++) {
			for (int j = 0; j < BOARD_DIMENSION; j++) {

				if ((i == 0) && (j < 5))
					gameBoardReference[i][j] = 0;
				else if ((i == 1) && (j < 6))
					gameBoardReference[i][j] = 0;
				else if ((i == 2) && (j < 7))
					gameBoardReference[i][j] = 0;
				else if ((i == 3) && (j < 8))
					gameBoardReference[i][j] = 0;
				else if ((i == 4) && (j < 9))
					gameBoardReference[i][j] = 0;
				else if ((i == 5) && (j > 0))
					gameBoardReference[i][j] = 0;
				else if ((i == 6) && (j > 1))
					gameBoardReference[i][j] = 0;
				else if ((i == 7) && (j > 2))
					gameBoardReference[i][j] = 0;
				else if ((i == 8) && (j > 3))
					gameBoardReference[i][j] = 0;
				else
					gameBoardReference[i][j] = -1;
			}
		}

		return Tools.getMatrixClone(gameBoardReference);
	}
	
	public static boolean positionHaveNoOwner(int x, int y) {
		boolean isValid = true;

		if ((x < 0) || (x >= Tetralath.BOARD_DIMENSION) || (y < 0) || (y >= Tetralath.BOARD_DIMENSION))
			isValid = false;
		else
			isValid = (Tetralath.gameBoard[x][y] == 0);

		return isValid;
	}
	
	/**
	 * Checks whether the given position is inside the game board (is valid)
	 * 
	 * @param x - x position
	 * @param y - y position
	 * @return true if position is valid and false otherwise
	 */
	public static boolean isPositionValid(int x, int y) {
		boolean isValid = true;

		if ((x < 0) || (x >= Tetralath.BOARD_DIMENSION) || (y < 0) || (y >= Tetralath.BOARD_DIMENSION))
			isValid = false;
		else
			isValid = (Tetralath.gameBoard[x][y] != -1);

		return isValid;
	}
}
